package com.crr.mall.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.crr.mall.common.bean.ResultBean;
import com.crr.mall.common.to.SkuRelationTO;
import com.crr.mall.common.to.SpuBoundsTO;
import com.crr.mall.common.to.StockVO;
import com.crr.mall.common.to.es.SkuEsModel;
import com.crr.mall.common.utils.Assert;
import com.crr.mall.common.utils.R;
import com.crr.mall.product.dao.*;
import com.crr.mall.product.entity.*;
import com.crr.mall.product.feign.CouponFeignService;
import com.crr.mall.product.feign.ESFeignService;
import com.crr.mall.product.feign.WareFeignService;
import com.crr.mall.product.service.BrandService;
import com.crr.mall.product.service.CategoryService;
import com.crr.mall.product.vo.SpuVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.temporal.ValueRange;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crr.mall.common.utils.PageUtils;
import com.crr.mall.common.utils.Query;

import com.crr.mall.product.service.SpuService;
import org.springframework.transaction.annotation.Transactional;


@Service("spuService")
@Slf4j
public class SpuServiceImpl extends ServiceImpl<SpuDao, SpuEntity> implements SpuService {
    @Autowired
    SpuDescDao spuDescDao;
    @Autowired
    SpuImagesDao spuImagesDao;
    @Autowired
    SpuAttrValueDao spuAttrValueDao;
    @Autowired
    SkuDao skuDao;
    @Autowired
    SkuImagesDao skuImagesDao;
    @Autowired
    BrandService brandService;
    @Autowired
    CategoryService categoryService;
    @Autowired
    SkuSaleAttrValueDao skuSaleAttrValueDao;
    @Autowired
    CouponFeignService couponFeignService;
    @Autowired
    AttrDao attrDao;
    @Autowired
    WareFeignService wareFeignService;
    @Autowired
    ESFeignService esFeignService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuEntity> page = this.page(
                new Query<SpuEntity>().getPage(params),
                new QueryWrapper<SpuEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public int saveDetail(SpuVO spuVO) {
        SpuEntity spuEntity = new SpuEntity();
        BeanUtil.copyProperties(spuVO, spuEntity);
        //保存spu基础信息
        int i = baseMapper.saveDetail(spuEntity);
        Assert.fail(i >= 1, "保存spu基础信息失败");
        //保存spu描述信息
        if (null != spuVO.getDecript() && spuVO.getDecript().size() > 0) {
            i = spuDescDao.saveDesc(spuEntity.getId(), spuVO.getDecript());
            Assert.fail(i >= 1, "保存spu描述图片信息失败");
        }
        //保存图片集
        if (null != spuVO.getImages() && spuVO.getImages().size() > 0) {
            int i1 = spuImagesDao.saveImages(spuEntity.getId(), spuVO.getImages());
            Assert.fail(i1 >= 1, "保存spu图片集信息失败");
        }
        //保存spu规格参数
        if (null != spuVO.getBaseAttrs() && spuVO.getBaseAttrs().size() > 0) {
            int i2 = spuAttrValueDao.saveAttrValue(spuEntity.getId(), spuVO.getBaseAttrs());
            Assert.fail(i2 >= 1, "保存spu规格参数信息失败");
        }
        //保存spu的积分信息 跨服务保存
        SpuBoundsTO spuBoundsTO = new SpuBoundsTO();
        BeanUtil.copyProperties(spuVO.getBounds(), spuBoundsTO);
        spuBoundsTO.setSpuId(spuEntity.getId());
        couponFeignService.saveBounds(spuBoundsTO);

        //保存spu对应的sku的所有信息
        if (null != spuVO.getSkus() && spuVO.getSkus().size() > 0) {
            SkuEntity skuEntity = new SkuEntity();
            spuVO.getSkus().forEach(sku -> {
                BeanUtil.copyProperties(sku, skuEntity);
                skuEntity.setSpuId(spuEntity.getId());
                skuEntity.setBrandId(spuVO.getBrandId());
                skuEntity.setCatelogId(spuVO.getCatelogId());
                int save = skuDao.saveSkus(skuEntity);
                Assert.fail(save >= 1, "保存sku参数信息失败");
                if (null != sku.getImages() && sku.getImages().size() > 0) {
                    save = skuImagesDao.saveImages(skuEntity.getSkuId(), sku.getImages());
                    Assert.fail(save >= 1, "保存sku图片信息失败");
                }
                if (null != sku.getAttr() && sku.getAttr().size() > 0) {
                    save = skuSaleAttrValueDao.saveValues(skuEntity.getSkuId(), sku.getAttr());
                    Assert.fail(save >= 1, "保存sku销售属性信息失败");
                }

                //保存spu的积分信息 跨服务保存
                SkuRelationTO skuRelationTO = new SkuRelationTO();
                BeanUtil.copyProperties(sku, skuRelationTO);
                skuRelationTO.setSkuId(skuEntity.getSkuId());
                if (sku.getFullCount() > 0 || sku.getFullPrice().compareTo(new BigDecimal("0")) == 1)
                    couponFeignService.saveSkuRelation(skuRelationTO);
            });

        }

        return 1;
    }

    @Override
    public PageUtils queryByCondition(Map<String, Object> map) {
        int page = Integer.parseInt(map.get("page").toString());
        int pageSize = Integer.parseInt(map.get("pageSize").toString());
        PageHelper.startPage(page, pageSize);
        List<Map> list = baseMapper.queryByCondition(map);
        PageInfo info = new PageInfo(list);
        return new PageUtils(list, (int) info.getTotal(), pageSize, page);
    }

    @Transactional
    @Override
    public void skuUp(Long spuId) {
        //组装需要的数据
        //attrs 根据sku查询到的所有的product_attr
        List<SkuEsModel.Attrs> attrs = new ArrayList<>();
        List<SpuAttrValueEntity> AttrValueEntity = spuAttrValueDao.getBySpuId(spuId);
        List<Long> attrIds = new ArrayList<>();
        AttrValueEntity.forEach(a -> {
            attrIds.add(a.getAttrId());
        });
        //远程调用ware服务查询是否有库存
        Map<Long, Boolean> stockMap = null;
        try {
            List<StockVO> stock = wareFeignService.getStock(attrIds);
            //按照skuId查询是否有库存
            stockMap = stock.stream().collect(Collectors.toMap(StockVO::getSkuId, item -> item.getHasStock()));
        } catch (Exception e) {
            log.error("库存服务查询异常：原因{}", e.getStackTrace());
        }

        //根据所有的id查询attr是否可被检索search_type=1
        List<Long> ids = attrDao.queryByattrId(attrIds);
        System.out.println(ids);
        //判断attrIds是否包含ids
        Set<Long> idSet = new HashSet<>(ids);
        List<SpuAttrValueEntity> collect = AttrValueEntity.stream().filter(item -> {
            return idSet.contains(item.getAttrId());
        }).collect(Collectors.toList());
        BeanUtil.copyProperties(collect, attrs);
        //根据spuId查询sku信息
        List<SkuEntity> skus = skuDao.queryBySpuId(spuId);
        List<Long> skuIds = new ArrayList<>();
        skus.forEach(sku -> {
            skuIds.add(sku.getSkuId());
        });
        //远程调用ware服务查询是否有库存

        Map<Long, Boolean> finalStockMap = stockMap;
        List<SkuEsModel> skuEsModelList = new ArrayList<>();
        skus.forEach(sku -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtil.copyProperties(sku, skuEsModel);//相同的数据对拷
            skuEsModel.setSkuPrice(sku.getPrice());
            skuEsModel.setSkuImg(sku.getSkuDefaultImg());
            //hasStock hotScore热度评分先设置为0
            skuEsModel.setHotScore(0L);
            if (finalStockMap == null) {
                skuEsModel.setHasStock(true);
            } else {
                skuEsModel.setHasStock(finalStockMap.get(sku.getSkuId()));
            }

            //brandName catelogName brandImg
            BrandEntity brand = brandService.getById(sku.getBrandId());
            skuEsModel.setBrandName(brand.getName());
            skuEsModel.setBrandImg(brand.getLogo());
            CategoryEntity catelog = categoryService.getById(sku.getCatelogId());
            skuEsModel.setCatelogName(catelog.getName());
            skuEsModel.setAttrs(attrs);

            skuEsModelList.add(skuEsModel);

        });
        //远程调用renrenmall-search接口商品上架
        ResultBean resultBean = esFeignService.productSearch(skuEsModelList);
        if (resultBean.getCode() == 200) {
            //远程调用成功 改掉当前spu的状态改为上架上架状态[0 - 新建   1上架，2 - 下架]
            int i = baseMapper.updateStatus(spuId);
            Assert.fail(i>=1,"修改spu状态失败");
        } else {
            //远程调用失败
        }
    }

}